package spring.cloud.tasks.executor.executor.task.task_configuration;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.common.SimpleSlicingTaskTaskItemCountAndLoadAndParameterInfo;
import spring.cloud.tasks.common.TaskBaseInfoDto;
import spring.cloud.tasks.common.TaskType;
import spring.cloud.tasks.common.curator.Curator;
import spring.cloud.tasks.common.nodepaths.TaskBaseInfoNode;
import spring.cloud.tasks.common.nodepaths.TaskNodePaths;

import java.util.HashMap;
import java.util.Map;


@Slf4j
@Setter
@Getter
public class TaskConfiguration {
    TaskBaseInfoDto baseInfoDto = new TaskBaseInfoDto();
    /**
     * 如果regCenter!=null, 取值从zk取
     */
    private Curator curator;
    private String taskId;
    /**
     * status代表启用和禁用 enable配置则代表是否任务进行调度。
     * 如果在启用的情况下可以进行调度。如果在禁用的情况下则不能进行调度。
     */
    private String status;
    private boolean enabled = true;
    /**
     * 任务允许延迟执行的秒数
     */
    private Integer secondAfterTaskStopCommandInstructed;


    public TaskConfiguration(Curator nameSpaceDataManager, String taskId) {
        this.taskId = taskId;
        this.curator = nameSpaceDataManager;
        reloadTaskBaseInfoDto();
    }


    public TaskBaseInfoDto getTaskBaseInfo() {
        if (this.baseInfoDto != null) {
            return this.baseInfoDto;
        } else {
            return reloadTaskBaseInfoDto();
        }
    }

    public TaskBaseInfoDto reloadTaskBaseInfoDto() {
        if (curator == null) {
            return null;
        }
        String taskId = this.taskId;
        TaskBaseInfoDto taskBaseInfoDto = new TaskBaseInfoDto();

        String taskVersionString = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.baseInfoNode));
        if ("".equals(taskVersionString)) {
            return this.baseInfoDto;
        }
        long taskVersion = Long.parseLong(taskVersionString);
        if (taskVersion <= Long.parseLong(taskBaseInfoDto.getTaskVersionString())) {
            return this.baseInfoDto;
        }
        String taskType = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.task_type));
        taskBaseInfoDto.setTaskType(taskType);

        String xId = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.xid));
        taskBaseInfoDto.setXid(xId);

        taskBaseInfoDto.setTaskId(taskId);
//        //
//        public static final String status = "status";


        String cronExpression = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.cron_expression));
        taskBaseInfoDto.setCronExpression(cronExpression);
        String pauseDatePeriod = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.pause_period_date));
        taskBaseInfoDto.setPausePeriodDate(pauseDatePeriod);
        String pauseTimePeriod = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.pause_period_time));
        taskBaseInfoDto.setPausePeriodTime(pauseTimePeriod);


        String timeoutMinutesStr = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.timeout_minutes));
        if (!Strings.isNullOrEmpty(timeoutMinutesStr)) {
            int timeoutMinutes = Integer.parseInt(timeoutMinutesStr);
            taskBaseInfoDto.setTimeoutMinutes(timeoutMinutes);
        }
        String timeoutAlarmMinutesStr = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.timeout_alarm_minutes));
        if (!Strings.isNullOrEmpty(timeoutAlarmMinutesStr)) {
            int timeoutAlarmMinutes = Integer.parseInt(timeoutAlarmMinutesStr);
            taskBaseInfoDto.setTimeoutAlarmMinutes(timeoutAlarmMinutes);
        }

        String taskProperties = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.task_properties));
        taskBaseInfoDto.setTaskProperties(taskProperties);

        String taskDataRangeRule = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.task_data_rang_rule));
        taskBaseInfoDto.setTaskDataRangeRule(taskDataRangeRule);

        String taskItemInfo = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskBaseInfoNode.task_item_info));
        taskBaseInfoDto.setTaskItemInfo(taskItemInfo);
        //
        this.baseInfoDto = taskBaseInfoDto;
        //
        String status = curator.getData(TaskNodePaths.getTaskNodePath(taskId, TaskNodePaths.status));
        this.status = status;
        return taskBaseInfoDto;
    }

    public boolean isDeleting() throws Exception {
        boolean delete = curator.checkExists(TaskNodePaths.getTaskNodePath(taskId, TaskNodePaths.delete));
        boolean to_delete = curator.checkExists(TaskNodePaths.getTaskNodePath(taskId, TaskNodePaths.to_delete));
        return delete || to_delete;
    }

    public Map<Integer, String> getTaskItemIndexToTaskItemParameterMap(String taskType, String taskItemInfo) {
        if (TaskType.SIMPLE_SLICING.equals(taskType)) {
            Map<Integer, String> taskItemIndexToTaskItemParameterMap = new HashMap<>();
            if (Strings.isNullOrEmpty(taskItemInfo)) {
                return taskItemIndexToTaskItemParameterMap;
            }
            SimpleSlicingTaskTaskItemCountAndLoadAndParameterInfo simpleSlicingTaskTaskItemCountAndLoadAndParameterInfo = JSON.parseObject(taskItemInfo, SimpleSlicingTaskTaskItemCountAndLoadAndParameterInfo.class);
            int taskItemCount = simpleSlicingTaskTaskItemCountAndLoadAndParameterInfo.taskItemCount;
            int taskItemLoad = simpleSlicingTaskTaskItemCountAndLoadAndParameterInfo.taskItemLoad;
            String taskItemIndexAndTaskItemParametersString = simpleSlicingTaskTaskItemCountAndLoadAndParameterInfo.getTaskItemIndexAndTaskItemParametersString();
            String taskItemPropertiesString = simpleSlicingTaskTaskItemCountAndLoadAndParameterInfo.taskItemPropertiesString;
            JSONArray jsonArray = JSON.parseArray(taskItemIndexAndTaskItemParametersString);
            for (Object object : jsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                String taskItemIndex = jsonObject.getString("taskItemIndex");
                String taskItemParameter = jsonObject.getString("taskItemParameter");
                taskItemIndexToTaskItemParameterMap.put(Integer.valueOf(taskItemIndex), taskItemParameter);
            }
            return taskItemIndexToTaskItemParameterMap;
        } else {
            throw new UnsupportedOperationException();
        }

    }


}